package booyah.service;

import java.util.List;
import java.util.Random;

import org.springframework.orm.jpa.JpaTemplate;
import org.springframework.orm.jpa.support.JpaDaoSupport;

import booyah.application.Person;

public class PersonServiceImpl extends JpaDaoSupport implements PersonService {

	public void createPerson(final Person person) {
		if (person.getId() != null)
			throw new IllegalArgumentException("Not a new person.");
		getJpaTemplate().persist(person);
	}

	public void updatePerson(final Person person) {
		JpaTemplate jpaTemplate = getJpaTemplate();
		jpaTemplate.persist(jpaTemplate.contains(person) ? person : jpaTemplate.merge(person));
	}

	public void deletePerson(Person person) {
		JpaTemplate jpaTemplate = getJpaTemplate();
		jpaTemplate.remove(jpaTemplate.contains(person) ? person : jpaTemplate.merge(person));
	}

	public boolean authenticate(String email, String password) {
		assert (email != null);
		assert (password != null);
		Person person = findPersonByEmail(email);
		// TODO This should incorporate MD5 hash or some other mechanism to
		// protect the password.
		return (person == null) ? false : password.equals(person.getPassword());
	}

	@SuppressWarnings("unchecked")
	public String resetPassword(String email) {
		List<Person> persons = getJpaTemplate().find("from Person p where p.email = ?", email);
		assert(persons.size() < 2);
		return persons.size() == 0 ? null : resetPassword(persons.get(0));
	}

	public String resetPassword(Person person) {
		String newPassword = generateRandomString(8);
		person.setPassword(newPassword);
		updatePerson(person);
		return newPassword;
	}

	static protected String generateRandomString(final int length) {
		String charset = "!0123456789abcdefghijklmnopqrstuvwxyz";
		Random rand = new Random(System.currentTimeMillis());
		StringBuffer sb = new StringBuffer();
		for (int i = 0; i <= length; i++) {
			int pos = rand.nextInt(15);
			sb.append(charset.charAt(pos));
		}
		return sb.toString();
	}

	@SuppressWarnings("unchecked")
	public Person findPersonByEmail(String email) {
		List<Person> persons = getJpaTemplate().find("from Person p where p.email = ?", email);
		assert (persons.size() < 2);
		return persons.isEmpty() ? null : persons.get(0);
	}

}
